using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using JGSY.CMS.LowCode.Platform.Infrastructure.Configuration.Models;
using JGSY.CMS.LowCode.Platform.Infrastructure.Services.Notification;
using System.Text.Json;
using System.ComponentModel.DataAnnotations;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Configuration;

/// <summary>
/// 增强版配置映射工厂
/// 提供完整的 appsettings.json 映射到强类型对象的功能
/// </summary>
public class EnhancedConfigurationMappingFactory
{
    private readonly EnhancedAppSettingsMapper _mapper;
    private readonly ILogger<EnhancedConfigurationMappingFactory>? _logger;
    private readonly IConfiguration _configuration;

    public EnhancedConfigurationMappingFactory(
        IConfiguration configuration, 
        ILogger<EnhancedConfigurationMappingFactory>? logger = null)
    {
        _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
        // 创建EnhancedAppSettingsMapper时不传递日志器，避免类型不匹配
        _mapper = new EnhancedAppSettingsMapper(configuration);
        _logger = logger;
    }

    #region 核心配置获取方法

    /// <summary>
    /// 获取完整的应用配置映射（所有配置的汇总）
    /// </summary>
    /// <returns>完整的配置对象</returns>
    public EnhancedAppSettingsConfiguration GetCompleteApplicationSettings()
    {
        _logger?.LogInformation("开始加载完整的应用配置映射...");
        
        var stopwatch = System.Diagnostics.Stopwatch.StartNew();
        
        try
        {
            var config = new EnhancedAppSettingsConfiguration
            {
                // 基础配置
                Database = GetDatabaseConfiguration(),
                Logging = GetLoggingConfiguration(),
                SerilogCust = GetSerilogCustConfiguration(),
                Serilog = GetSerilogConfiguration(),
                Jwt = GetJwtConfiguration(),
                Server = GetServerConfiguration(),
                CacheSettings = GetCacheSettingsConfiguration(),
                AllowedHosts = GetAllowedHostsConfiguration(),

                // 扩展配置
                Security = GetSecurityConfiguration(),
                Upload = GetUploadConfiguration(),
                Sms = GetSmsConfiguration(),
                Cors = GetCorsConfiguration(),
                Api = GetApiConfiguration(),
                RateLimit = GetRateLimitConfiguration(),
                Lock = GetLockConfiguration(),
                Permission = GetPermissionConfiguration(),
                Extension = GetExtensionConfiguration(),
                MongoDb = GetMongoDbConfiguration(),
                ClickHouse = GetClickHouseConfiguration(),

                // 元数据
                LoadedAt = DateTime.UtcNow,
                Version = GetConfigurationVersion(),
                Environment = GetEnvironmentName()
            };

            stopwatch.Stop();
            _logger?.LogInformation("完整的应用配置映射加载完成，耗时: {ElapsedMs}ms", stopwatch.ElapsedMilliseconds);
            
            return config;
        }
        catch (Exception ex)
        {
            stopwatch.Stop();
            _logger?.LogError(ex, "加载完整的应用配置映射失败，耗时: {ElapsedMs}ms", stopwatch.ElapsedMilliseconds);
            throw new InvalidOperationException("Failed to load complete application settings", ex);
        }
    }

    /// <summary>
    /// 获取数据库配置映射
    /// </summary>
    public DatabaseConfiguration GetDatabaseConfiguration()
    {
        try
        {
            var config = _mapper.BindRoot<DatabaseConfiguration>();
            ValidateDatabaseConfiguration(config);
            return config;
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, "Failed to load database configuration");
            throw new ConfigurationException("Database configuration mapping failed", ex);
        }
    }

    /// <summary>
    /// 获取日志配置映射
    /// </summary>
    public LoggingConfiguration GetLoggingConfiguration()
    {
        return _mapper.Bind<LoggingConfiguration>("Logging");
    }

    /// <summary>
    /// 获取 Serilog 自定义配置映射
    /// </summary>
    public SerilogCustConfiguration GetSerilogCustConfiguration()
    {
        return _mapper.Bind<SerilogCustConfiguration>("SerilogCust");
    }

    /// <summary>
    /// 获取 Serilog 完整配置映射
    /// </summary>
    public SerilogConfiguration GetSerilogConfiguration()
    {
        return _mapper.Bind<SerilogConfiguration>("Serilog");
    }

    /// <summary>
    /// 获取 JWT 配置映射
    /// </summary>
    public JwtConfiguration GetJwtConfiguration()
    {
        var config = _mapper.Bind<JwtConfiguration>("Jwt");
        ValidateJwtConfiguration(config);
        return config;
    }

    /// <summary>
    /// 获取服务器配置映射
    /// </summary>
    public ServerConfiguration GetServerConfiguration()
    {
        return _mapper.Bind<ServerConfiguration>("Server");
    }

    /// <summary>
    /// 获取缓存设置配置映射
    /// </summary>
    public CacheSettingsConfiguration GetCacheSettingsConfiguration()
    {
        return _mapper.Bind<CacheSettingsConfiguration>("CacheSettings");
    }

    /// <summary>
    /// 获取允许的主机配置映射
    /// </summary>
    public AllowedHostsConfiguration GetAllowedHostsConfiguration()
    {
        var hosts = _mapper.GetValue<string>("AllowedHosts", "*");
        return new AllowedHostsConfiguration { Hosts = hosts };
    }

    #endregion

    #region 扩展配置映射方法

    /// <summary>
    /// 获取安全配置映射
    /// </summary>
    public SecurityConfiguration GetSecurityConfiguration()
    {
        return _mapper.Bind<SecurityConfiguration>("CacheSettings:Security");
    }

    /// <summary>
    /// 获取上传配置映射
    /// </summary>
    public UploadConfiguration GetUploadConfiguration()
    {
        return _mapper.Bind<UploadConfiguration>("CacheSettings:Upload");
    }

    /// <summary>
    /// 获取SMS配置映射 - 企业级短信服务配置
    /// </summary>
    public SmsServiceOptions GetSmsConfiguration()
    {
        try
        {
            var config = _mapper.Bind<SmsServiceOptions>("SmsService");
            _logger?.LogInformation("SMS service configuration loaded: Provider={Provider}, EnableFailover={EnableFailover}", 
                config.DefaultProvider, config.EnableFailover);
            return config;
        }
        catch (Exception ex)
        {
            _logger?.LogWarning(ex, "Failed to load SMS service configuration from 'SmsService' section, trying fallback...");
            
            // 提供默认配置以确保兼容性
            return new SmsServiceOptions
            {
                DefaultProvider = "aliyun",
                EnableFailover = true,
                RetryCount = 3,
                EnableRateLimit = true,
                MaxSendPerMinute = 60,
                MaxSendPerHourPerPhone = 10
            };
        }
    }

    /// <summary>
    /// 获取云存储配置映射
    /// </summary>
    public CloudStorageConfiguration GetCloudStorageConfiguration()
    {
        return _mapper.Bind<CloudStorageConfiguration>("CloudStorage");
    }

    /// <summary>
    /// 获取CORS配置映射
    /// </summary>
    public CorsConfiguration GetCorsConfiguration()
    {
        return _mapper.Bind<CorsConfiguration>("CacheSettings:Cors");
    }

    /// <summary>
    /// 获取API配置映射
    /// </summary>
    public ApiConfiguration GetApiConfiguration()
    {
        return _mapper.Bind<ApiConfiguration>("CacheSettings:Api");
    }

    /// <summary>
    /// 获取速率限制配置映射
    /// </summary>
    public RateLimitConfiguration GetRateLimitConfiguration()
    {
        return _mapper.Bind<RateLimitConfiguration>("CacheSettings:RateLimit");
    }

    /// <summary>
    /// 获取锁定配置映射
    /// </summary>
    public LockConfiguration GetLockConfiguration()
    {
        return _mapper.Bind<LockConfiguration>("CacheSettings:Locked");
    }

    /// <summary>
    /// 获取权限配置映射
    /// </summary>
    public PermissionConfiguration GetPermissionConfiguration()
    {
        return _mapper.Bind<PermissionConfiguration>("Permission");
    }

    /// <summary>
    /// 获取扩展配置映射
    /// </summary>
    public ExtensionConfiguration GetExtensionConfiguration()
    {
        return _mapper.Bind<ExtensionConfiguration>("CacheSettings:Extension");
    }

    /// <summary>
    /// 获取MongoDB配置映射
    /// </summary>
    public MongoDbConfiguration GetMongoDbConfiguration()
    {
        return _mapper.Bind<MongoDbConfiguration>("CacheSettings:MongoDb");
    }

    /// <summary>
    /// 获取ClickHouse配置映射
    /// </summary>
    public ClickHouseConfiguration GetClickHouseConfiguration()
    {
        return _mapper.Bind<ClickHouseConfiguration>("CacheSettings:ClickHouse");
    }

    #endregion

    #region 配置分析和诊断方法

    /// <summary>
    /// 获取配置健康状态
    /// </summary>
    public ConfigurationHealthReport GetHealthReport()
    {
        var report = new ConfigurationHealthReport
        {
            CheckedAt = DateTime.UtcNow,
            IsHealthy = true,
            Issues = new List<string>(),
            Warnings = new List<string>(),
            Sections = new List<ConfigurationSectionHealth>()
        };

        try
        {
            // 检查关键配置节
            CheckConfigurationSection(report, "Database", () => GetDatabaseConfiguration());
            CheckConfigurationSection(report, "Jwt", () => GetJwtConfiguration());
            CheckConfigurationSection(report, "Server", () => GetServerConfiguration());
            CheckConfigurationSection(report, "CacheSettings", () => GetCacheSettingsConfiguration());
            CheckConfigurationSection(report, "Logging", () => GetLoggingConfiguration());

            report.IsHealthy = report.Issues.Count == 0;
            
            _logger?.LogInformation("Configuration health check completed. Healthy: {IsHealthy}, Issues: {IssueCount}, Warnings: {WarningCount}",
                report.IsHealthy, report.Issues.Count, report.Warnings.Count);
        }
        catch (Exception ex)
        {
            report.IsHealthy = false;
            report.Issues.Add($"Health check failed: {ex.Message}");
            _logger?.LogError(ex, "Configuration health check failed");
        }

        return report;
    }

    /// <summary>
    /// 获取配置元数据
    /// </summary>
    public ConfigurationMetadata GetConfigurationMetadata()
    {
        var allConfig = _mapper.GetAllConfiguration();
        
        return new ConfigurationMetadata
        {
            TotalKeys = allConfig.Count,
            Sections = GetConfigurationSections(),
            Environment = GetEnvironmentName(),
            LastReloadTime = DateTime.UtcNow,
            CacheStats = _mapper.GetCacheStats(),
            Sources = GetConfigurationSources()
        };
    }

    /// <summary>
    /// 导出配置为JSON（隐藏敏感信息）
    /// </summary>
    public string ExportConfigurationAsJson(bool includeSensitive = false)
    {
        try
        {
            var config = GetCompleteApplicationSettings();
            
            if (!includeSensitive)
            {
                // 隐藏敏感信息
                HideSensitiveData(config);
            }

            var options = new JsonSerializerOptions
            {
                WriteIndented = true,
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            };

            return JsonSerializer.Serialize(config, options);
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, "Failed to export configuration as JSON");
            throw;
        }
    }

    /// <summary>
    /// 验证配置完整性
    /// </summary>
    public EnhancedConfigurationValidationResult ValidateAllConfigurations()
    {
        var result = new EnhancedConfigurationValidationResult
        {
            IsValid = true,
            Errors = new List<string>(),
            Warnings = new List<string>(),
            ValidatedAt = DateTime.UtcNow
        };

        try
        {
            // 验证各个配置节
            ValidateConfigurationSection<DatabaseConfiguration>(result, "Database", GetDatabaseConfiguration);
            ValidateConfigurationSection<JwtConfiguration>(result, "Jwt", GetJwtConfiguration);
            ValidateConfigurationSection<ServerConfiguration>(result, "Server", GetServerConfiguration);
            ValidateConfigurationSection<CacheSettingsConfiguration>(result, "CacheSettings", GetCacheSettingsConfiguration);

            result.IsValid = result.Errors.Count == 0;
            
            _logger?.LogInformation("Configuration validation completed. Valid: {IsValid}, Errors: {ErrorCount}, Warnings: {WarningCount}",
                result.IsValid, result.Errors.Count, result.Warnings.Count);
        }
        catch (Exception ex)
        {
            result.IsValid = false;
            result.Errors.Add($"Validation failed: {ex.Message}");
            _logger?.LogError(ex, "Configuration validation failed");
        }

        return result;
    }

    #endregion

    #region 辅助方法

    /// <summary>
    /// 获取数据库类型
    /// </summary>
    /// <returns>数据库类型</returns>
    public string GetDatabaseType()
    {
        return _mapper.GetValue<string>("DatabaseType") ?? "SQLite";
    }

    /// <summary>
    /// 获取Serilog自定义配置的特定值
    /// </summary>
    /// <typeparam name="T">值类型</typeparam>
    /// <param name="key">配置键</param>
    /// <param name="defaultValue">默认值</param>
    /// <returns>配置值</returns>
    public T GetSerilogCustomValue<T>(string key, T defaultValue = default!)
    {
        return _mapper.GetValue<T>($"SerilogCust:{key}", defaultValue);
    }

    /// <summary>
    /// 获取权限配置的特定值
    /// </summary>
    /// <typeparam name="T">值类型</typeparam>
    /// <param name="key">配置键</param>
    /// <param name="defaultValue">默认值</param>
    /// <returns>配置值</returns>
    public T GetPermissionValue<T>(string key, T defaultValue = default!)
    {
        return _mapper.GetValue<T>($"Permission:{key}", defaultValue);
    }

    /// <summary>
    /// 获取缓存配置映射
    /// </summary>
    public CacheConfiguration GetCacheConfiguration()
    {
        return _mapper.Bind<CacheConfiguration>("Cache");
    }

    /// <summary>
    /// 获取应用程序环境名称
    /// </summary>
    /// <returns>环境名称</returns>
    public string GetEnvironmentName()
    {
        return _mapper.GetValue<string>("ASPNETCORE_ENVIRONMENT") ?? 
               _mapper.GetValue<string>("Server:Environment") ?? 
               "Development";
    }

    /// <summary>
    /// 获取配置版本信息
    /// </summary>
    /// <returns>配置版本</returns>
    public string GetConfigurationVersion()
    {
        return _mapper.GetValue<string>("Application:Version") ?? "1.0.0";
    }

    private void ValidateDatabaseConfiguration(DatabaseConfiguration config)
    {
        var connectionString = config.ConnectionStrings?.GetConnectionString(config.DatabaseType);
        
        if (string.IsNullOrEmpty(connectionString))
        {
            throw new ConfigurationException($"Connection string for database type '{config.DatabaseType}' is not configured.");
        }
    }

    private void ValidateJwtConfiguration(JwtConfiguration config)
    {
        if (string.IsNullOrEmpty(config.Secret))
        {
            throw new ConfigurationException("JWT Secret is required but not configured.");
        }

        if (config.Secret.Length < 32)
        {
            _logger?.LogWarning("JWT Secret should be at least 32 characters long for security.");
        }
    }

    private void CheckConfigurationSection<T>(ConfigurationHealthReport report, string sectionName, Func<T> configGetter) where T : class
    {
        var sectionHealth = new ConfigurationSectionHealth
        {
            SectionName = sectionName,
            IsHealthy = true,
            Issues = new List<string>()
        };

        try
        {
            var config = configGetter();
            // 执行基本验证
            var context = new ValidationContext(config);
            var results = new List<ValidationResult>();
            
            if (!Validator.TryValidateObject(config, context, results, true))
            {
                sectionHealth.IsHealthy = false;
                sectionHealth.Issues.AddRange(results.Select(r => r.ErrorMessage ?? "Validation error"));
                report.Issues.AddRange(sectionHealth.Issues.Select(issue => $"{sectionName}: {issue}"));
            }
        }
        catch (Exception ex)
        {
            sectionHealth.IsHealthy = false;
            sectionHealth.Issues.Add($"Failed to load: {ex.Message}");
            report.Issues.Add($"{sectionName}: {ex.Message}");
        }

        report.Sections.Add(sectionHealth);
        if (!sectionHealth.IsHealthy)
        {
            report.IsHealthy = false;
        }
    }

    private void ValidateConfigurationSection<T>(EnhancedConfigurationValidationResult result, string sectionName, Func<T> configGetter) where T : class
    {
        try
        {
            var config = configGetter();
            var context = new ValidationContext(config);
            var validationResults = new List<ValidationResult>();
            
            if (!Validator.TryValidateObject(config, context, validationResults, true))
            {
                result.Errors.AddRange(validationResults.Select(vr => $"{sectionName}: {vr.ErrorMessage}"));
            }
        }
        catch (Exception ex)
        {
            result.Errors.Add($"{sectionName}: {ex.Message}");
        }
    }

    private List<string> GetConfigurationSections()
    {
        return _configuration.GetChildren().Select(c => c.Key).ToList();
    }

    private List<string> GetConfigurationSources()
    {
        // 这里可以根据实际的配置提供程序返回源信息
        return new List<string> { "appsettings.json", "Environment Variables", "Command Line" };
    }

    private void HideSensitiveData(EnhancedAppSettingsConfiguration config)
    {
        // 隐藏敏感的配置信息
        if (config.Database?.ConnectionStrings != null)
        {
            config.Database.ConnectionStrings.SqlServer = HideSensitiveValue(config.Database.ConnectionStrings.SqlServer);
            config.Database.ConnectionStrings.MySql = HideSensitiveValue(config.Database.ConnectionStrings.MySql);
            config.Database.ConnectionStrings.Postgres = HideSensitiveValue(config.Database.ConnectionStrings.Postgres);
            config.Database.ConnectionStrings.Sqlite = HideSensitiveValue(config.Database.ConnectionStrings.Sqlite);
        }

        if (config.Jwt != null)
        {
            config.Jwt.Secret = HideSensitiveValue(config.Jwt.Secret);
        }

        if (config.Security != null)
        {
            config.Security.CsrfSecret = HideSensitiveValue(config.Security.CsrfSecret);
            config.Security.SessionSecret = HideSensitiveValue(config.Security.SessionSecret);
        }
    }

    private string HideSensitiveValue(string? value)
    {
        if (string.IsNullOrEmpty(value))
            return string.Empty;
        
        return value.Length > 8 ? value[..4] + "****" + value[^4..] : "****";
    }

    #endregion

    #region 便利方法 - 连接字符串和路径

    /// <summary>
    /// 获取数据库连接字符串
    /// </summary>
    /// <param name="name">连接字符串名称，默认为"DefaultConnection"</param>
    /// <returns>连接字符串</returns>
    public string GetConnectionString(string name = "DefaultConnection")
    {
        var connectionString = _configuration.GetConnectionString(name);
        _logger?.LogDebug("Connection string '{Name}' loaded: {HasValue}", name, !string.IsNullOrEmpty(connectionString));
        return connectionString ?? string.Empty;
    }

    /// <summary>
    /// 获取Redis连接字符串
    /// </summary>
    /// <returns>Redis连接字符串</returns>
    public string GetRedisConnectionString()
    {
        return GetConnectionString("Redis");
    }

    /// <summary>
    /// 获取上传文件路径
    /// </summary>
    /// <returns>上传文件路径</returns>
    public string GetUploadPath()
    {
        var uploadConfig = GetUploadConfiguration();
        var path = uploadConfig.UploadPath ?? Path.Combine(Directory.GetCurrentDirectory(), "uploads");
        _logger?.LogDebug("Upload path resolved: {Path}", path);
        return path;
    }

    /// <summary>
    /// 获取文件上传基础URL
    /// </summary>
    /// <returns>文件上传基础URL</returns>
    public string GetUploadBaseUrl()
    {
        var uploadConfig = GetUploadConfiguration();
        var baseUrl = uploadConfig.BaseUrl ?? "http://localhost:5000";
        _logger?.LogDebug("Upload base URL resolved: {BaseUrl}", baseUrl);
        return baseUrl;
    }

    #endregion

    #region 缓存管理

    /// <summary>
    /// 清除所有缓存
    /// </summary>
    public void ClearCache()
    {
        _mapper.ClearCache();
        _logger?.LogDebug("Configuration mapping cache cleared");
    }

    #endregion
}

#region 辅助类和异常

/// <summary>
/// 配置异常
/// </summary>
public class ConfigurationException : Exception
{
    public ConfigurationException(string message) : base(message) { }
    public ConfigurationException(string message, Exception innerException) : base(message, innerException) { }
}

/// <summary>
/// 配置健康报告
/// </summary>
public class ConfigurationHealthReport
{
    public bool IsHealthy { get; set; }
    public DateTime CheckedAt { get; set; }
    public List<string> Issues { get; set; } = new();
    public List<string> Warnings { get; set; } = new();
    public List<ConfigurationSectionHealth> Sections { get; set; } = new();
}

/// <summary>
/// 配置节健康状态
/// </summary>
public class ConfigurationSectionHealth
{
    public string SectionName { get; set; } = string.Empty;
    public bool IsHealthy { get; set; }
    public List<string> Issues { get; set; } = new();
}

/// <summary>
/// 配置验证结果 - 增强版
/// </summary>
public class EnhancedConfigurationValidationResult
{
    public bool IsValid { get; set; } = true;
    public List<string> Errors { get; set; } = new();
    public List<string> Warnings { get; set; } = new();
    public DateTime ValidatedAt { get; set; }
}

/// <summary>
/// 配置元数据
/// </summary>
public class ConfigurationMetadata
{
    public int TotalKeys { get; set; }
    public List<string> Sections { get; set; } = new();
    public string Environment { get; set; } = string.Empty;
    public DateTime LastReloadTime { get; set; }
    public ConfigurationCacheStats CacheStats { get; set; } = new();
    public List<string> Sources { get; set; } = new();
}

#endregion
